//
//  uiMenuBar.cpp
//  trail-map-editor
//
//  Created by Giorgio Tino on 3/20/13.
//
//

#include "ui.h"

using namespace tinyxml2;

uiMenuBar::uiMenuBar(int h) : puMenuBar(h)
, submenus(0)
, submenu(0)
{
}

uiMenuBar::~uiMenuBar()
{	
	if(submenus)
	{
		for(unsigned int i = 0; i < submenus->getNumEntities(); i++)
		{
			uiSubmenu* item = (uiSubmenu*)submenus->getEntity(i);
			delete item;
		}
		
		delete submenus;
		submenus = NULL;
	}
	
	submenu = NULL;
	
	cleanUpUserData();
}

void uiMenuBar::cleanUpUserData()
{
	puObject* current = this->getFirstChild();
	
	while(current)
	{
		if(current->getType() & PUCLASS_POPUPMENU)
		{
			puPopupMenu* popupMenu = (puPopupMenu*)current;
			
			puObject* submenu = popupMenu->getFirstChild();
			
			while(submenu)
			{
				uiData* sdata = (uiData*)submenu->getUserData();
				
				if(sdata)
				{
					delete sdata;
					submenu->setUserData(0);
				}
				
				submenu = submenu->getNextObject();
			}
		}
		
		current = current->getNextObject();
	}
	
	uiData* data = (uiData*)this->getUserData();
	
	if(data)
	{
		delete data;
		data = 0;
		this->setUserData(0);
	}
}


puObject* uiMenuBar::findByName(const char* name)
{
	puObject* current = this->getFirstChild();
	
	while(current)
	{
		if(current->getType() & PUCLASS_POPUPMENU)
		{
			puPopupMenu* popupMenu = (puPopupMenu*)current;
			
			puObject* submenu = popupMenu->getFirstChild();
			
			while(submenu)
			{
				uiData* data = (uiData*)submenu->getUserData();
				
				if(data && data->name)
				{
					if(ulStrEqual(data->name,name))
						return submenu;
				}
				
				submenu = submenu->getNextObject();
			}
		}
		
		current = current->getNextObject();
	}
	
	return NULL;
}

void uiMenuBar::addSubmenu(const char* str)
{
	if(!submenus)
	{
		submenus = new ulList();
	}
	
	submenu = new uiSubmenu(str);
	submenus->addEntity(submenu);
}

void uiMenuBar::addSubmenuItem(const char* name, const char* legend)
{	
	if(submenu)
	{
		submenu->addItem(name,legend);
	}
}

void uiMenuBar::addSeparator()
{
	if(submenu)
	{
		submenu->addItem(NULL,"============");
	}
}

void uiMenuBar::closeSubmenu()
{
	if(!submenu)
		return;
	
	unsigned int n = submenu->getNumItems();
	char** items = new char*[n+1];
	puCallback* callbacks = new puCallback[n+1];
	void** userData = new void*[n+1];
	
	uiData* data = (uiData*)this->getUserData();

	for(unsigned int i = 0; i < n; i++)
	{
		uiSubmenuItem* item = submenu->getItem(n-i-1);
		
		items[i] = item->getLegend();
		
		callbacks[i] = item->getName() ? this->getCallback() : NULL;
		userData[i] = new uiData(item->getName(), data ? data->view : NULL);
	}
	
	items[n] = NULL;
	callbacks[n] = NULL;
	userData[n] = NULL;
	
	this->add_submenu(submenu->getName(), items, callbacks, userData);
	
	submenu = NULL; // current
}

void uiMenuBar::load(const tinyxml2::XMLElement* element)
{
	uiData* data = (uiData*)this->getUserData();
	
	if(!data)
		ulSetError(UL_WARNING,"uiMenuBar::load() called before the user data was set. Callbacks won't work!");
	
	if(element)
		parseElement(element->FirstChildElement());
}

void uiMenuBar::parseElement(const tinyxml2::XMLElement* element)
{
	const XMLElement* sibling = element;
	
	while(sibling)
	{		
		beginElement(sibling);
		
		const XMLElement* child = sibling->FirstChildElement();
		
		if(child)
			parseElement(child);
		
		endElement(sibling);
		
		sibling = sibling->NextSiblingElement();
	}
}

void uiMenuBar::beginElement(const XMLElement* element)
{
	if(XMLUtil::StringEqual( element->Name(), "submenu" ))
    {        			
		const char* legend = element->Attribute("legend");
		
		this->addSubmenu(legend);
    }
	else if(XMLUtil::StringEqual( element->Name(), "submenuitem" ))
    {        
		const char* name = element->Attribute("name");
		const char* legend = element->Attribute("legend");
		
		this->addSubmenuItem(name, legend);
    }
	else if(XMLUtil::StringEqual( element->Name(), "separator" ))
    {        		
		this->addSeparator();
    }
}

void uiMenuBar::endElement(const XMLElement* element)
{
	if(XMLUtil::StringEqual( element->Name(), "submenu" ))
    {  
		this->closeSubmenu();
	}
}